package com.pzr.soccer.dao.impl;

import com.pzr.soccer.dao.PlanDataHelper;
import com.pzr.soccer.domain.Plan;
import com.pzr.soccer.watched.PlanObserver;
import com.pzr.soccer.watched.PlanWatched;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.security.core.parameters.P;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * repository实现类，同时实现watched，plan更新后，会通知observers作出改变（比如scanChangeGameProcessor里面的this.plans）
 * @Author pzr
 * @date:2021-12-15-16:39
 * @Description:
 **/
@Slf4j
public class PlanRepositoryImpl implements PlanDataHelper, PlanWatched {
    private Set<PlanObserver> observers=new HashSet<>();
    @Autowired
    MongoOperations operations;
    @Override
    public List<Plan> requestLightly() {
        List<Plan> plans=operations.findAll(Plan.class);
        plans.forEach(p->{
            p.getCorrectMatchesId().clear();
            p.getMatchesId().clear();
            p.setDescription("");
        });
        return plans;
    }

    /**
     * 只是update correctMatchIds , matchIds  ,  matchPreCondition , matchResult
     * @param plan
     */
    @Override
    public void updateAfterScanGame(Plan plan) {

        Plan plan_o = operations.findById(plan.getId(), Plan.class);
        if(plan_o==null){
            log.info("no such plan for update!"+plan.getId());
            return;
        }
        plan_o.setMatchResult(plan.getMatchResult());
        plan_o.setMatchPreCondition(plan.getMatchPreCondition());
        if(!plan.getMatchesId().isEmpty()){
            plan_o.getMatchesId().addAll(plan.getMatchesId());
        }

        if(!plan.getCorrectMatchesId().isEmpty()){
            plan_o.getCorrectMatchesId().addAll(plan.getCorrectMatchesId());
        }
        operations.save(plan_o);

        //通知观察者们
        updateNotify(plan_o);

    }


    @Override
    public Plan saveAndNotify(Plan plan) {
       Plan save= operations.save(plan);
        updateNotify(save);
        return save;
    }


    @Override
    public void removeAndNotify(Plan plan) {
        operations.remove(plan);
        removeNotify(plan);
    }

    @Override
    public void removeAndNotify(String planId) {
      Plan plan1=  operations.findOne(Query.query(Criteria.where("id").is(planId)), Plan.class);
        assert plan1 != null;
        operations.remove(plan1);
        removeNotify(plan1);
    }


    @Override
    public void updateNotify(Plan plan) {
        for(PlanObserver observer:this.observers){
            observer.handleUpdate(plan);
        }
    }

    @Override
    public void removeNotify(Plan plan) {
        for(PlanObserver observer:this.observers){
            observer.handleRemove(plan);
        }
    }

    @Override
    public void registry(PlanObserver observer) {
         this.observers.add(observer);
    }

    @Override
    public void unRegistry(PlanObserver observer) {
         this.observers.remove(observer);
    }
}
